/*
 * This program is free software; you can redistribute it and/or modify it under the 
 * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software 
 * Foundation.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this 
 * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 
 * or from the Free Software Foundation, Inc., 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * Copyright 2008 Pentaho Corporation.  All rights reserved.
 *
 * @author Will Gorman (wgorman@pentaho.com)
 */
package org.pentaho.actioneditor.client.util;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;

public class EventRichFlexTable extends FlexTable {

  public static interface EventRichTableListener  extends TableListener {
    void onCellDblClicked(SourcesTableEvents sender, int row, int cell);
  }
  
  private class EventRichTableListenerCollection extends ArrayList {

    /**
     * Fires a cellClicked event to all listeners.
     * 
     * @param sender the widget sending the event
     * @param row the row of the cell being clicked
     * @param cell the index of the cell being clicked
     */
    public void fireCellClicked(SourcesTableEvents sender, int row, int cell) {
      for (Iterator it = iterator(); it.hasNext();) {
        TableListener listener = (TableListener) it.next();
        listener.onCellClicked(sender, row, cell);
      }
    }
    
    public void fireCellDblClicked(SourcesTableEvents sender, int row, int cell) {
      for (Iterator it = iterator(); it.hasNext();) {
        TableListener listener = (EventRichTableListener) it.next();
        if (listener instanceof EventRichTableListener) {
          ((EventRichTableListener)listener).onCellDblClicked(sender, row, cell);
        }
      }
    }
  }
  
  private EventRichTableListenerCollection tableListeners = null;
  
  
  public EventRichFlexTable() {
    super();
    sinkEvents(Event.ONCLICK | Event.ONDBLCLICK);
  }
  
  public void addTableListener(TableListener listener) {
    if (tableListeners == null) {
      tableListeners = new EventRichTableListenerCollection();
    }
    tableListeners.add(listener);
  }
  
  /**
   * Method to process events generated from the browser.
   * 
   * @param event the generated event
   */
  public void onBrowserEvent(Event event) {
    switch (DOM.eventGetType(event)) {
      case Event.ONCLICK: {
        if (tableListeners != null) {
          // Find out which cell was actually clicked.
          Element td = getEventTargetCell(event);
          if (td == null) {
            return;
          }
          Element tr = DOM.getParent(td);
          Element body = DOM.getParent(tr);
          int row = DOM.getChildIndex(body, tr);
          int column = DOM.getChildIndex(tr, td);
          // Fire the event.
          tableListeners.fireCellClicked(this, row, column);
        }
        break;
      }
      case Event.ONDBLCLICK: {
        if (tableListeners != null) {
          // Find out which cell was actually clicked.
          Element td = getEventTargetCell(event);
          if (td == null) {
            return;
          }
          Element tr = DOM.getParent(td);
          Element body = DOM.getParent(tr);
          int row = DOM.getChildIndex(body, tr);
          int column = DOM.getChildIndex(tr, td);
          // Fire the event.
          tableListeners.fireCellDblClicked(this, row, column);
        }
        break;
      }
      default: {
        // Do nothing
      }
    }
  }
  
  
}
